mw.track: Implement trackUnsubscribe
authorTimo Tijhof <krinklemail@gmail.com>
Fri, 27 Mar 2015 23:55:20 +0000 (23:55 +0000)
committerKrinkle <krinklemail@gmail.com>
Tue, 28 Apr 2015 16:52:49 +0000 (16:52 +0000)
Bug: T93986
Change-Id: I38219319cb7963f1f19ee81857dd084709fb6be1

resources/src/mediawiki/mediawiki.js
tests/qunit/suites/resources/mediawiki/mediawiki.track.test.js

index 237157c..e556ed8 100644 (file)
@@ -14,6 +14,7 @@
                hasOwn = Object.prototype.hasOwnProperty,
                slice = Array.prototype.slice,
                trackCallbacks = $.Callbacks( 'memory' ),
+               trackHandlers = [],
                trackQueue = [];
 
        /**
                 */
                trackSubscribe: function ( topic, callback ) {
                        var seen = 0;
-
-                       trackCallbacks.add( function ( trackQueue ) {
+                       function handler( trackQueue ) {
                                var event;
                                for ( ; seen < trackQueue.length; seen++ ) {
                                        event = trackQueue[ seen ];
                                                callback.call( event, event.topic, event.data );
                                        }
                                }
+                       }
+
+                       trackHandlers.push( [ handler, callback ] );
+
+                       trackCallbacks.add( handler );
+               },
+
+               /**
+                * Stop handling events for a particular handler
+                *
+                * @param {Function} callback
+                */
+               trackUnsubscribe: function ( callback ) {
+                       trackHandlers = $.grep( trackHandlers, function ( fns ) {
+                               if ( fns[1] === callback ) {
+                                       trackCallbacks.remove( fns[0] );
+                                       // Ensure the tuple is removed to avoid holding on to closures
+                                       return false;
+                               }
+                               return true;
                        } );
                },
 
index cdb2624..5329be6 100644 (file)
                        assert.assertTrue( this.timeStamp >= now, 'thisValue has sane timestamp' );
                } );
        } );
+
+       QUnit.test( 'trackUnsubscribe', 1, function ( assert ) {
+               var sequence = [];
+               function unsubber( topic, data ) {
+                       sequence.push( [ topic, data ] );
+               }
+
+               mw.track( 'unsub', { key: 1 } );
+               mw.trackSubscribe( 'unsub', unsubber );
+               mw.track( 'unsub', { key: 2 } );
+               mw.trackUnsubscribe( unsubber );
+               mw.track( 'unsub', { key: 3 } );
+
+               assert.deepEqual( sequence, [
+                       [ 'unsub', { key: 1 } ],
+                       [ 'unsub', { key: 2 } ]
+               ], 'Stop when unsubscribing' );
+       } );
 }( mediaWiki ) );